﻿using System;
using DG.Tweening;
using QF.Action;
using UniRx;
using UniRx.Triggers;
using UnityEngine;
using UnityEngine.UI;


namespace QF.Tetris
{
    public class PlayPanel : BasePanel
    {
        public Text   currentScoreText;
        public Text   highestScoreText;
        public Text   rowText;
        public Text   levelText;
        public Button pauseButton;

        public Button leftButton;
        public Button rightButton;
        public Button upButton;
        public Button downButton;
        public Button rocketButton;

        private Sequence mScoreSequence;


        void Awake()
        {
            Init();
        }

        public override BasePanel Show()
        {
            panelType = 0;
            if (!gameObject.activeSelf)
            {
                gameObject.SetActive(true);
            }

            currentScoreText.text = "0";
            highestScoreText.text = "0";
            rowText.text = "0";
            levelText.text = "0";
            EventManager.Instance.Fire(UIEvent.GET_SCORE_INFO, Convert.ToInt32(panelType));
            return this;
        }

        void LeftButtonClickRegister()
        {
            // 记录当前按钮是否正在按
            bool leftButtonPressing = false;
            
            // 长按的时候正在执行的任务
            IDisposable leftButtonLongPressTask = null;
            
            // 监听按钮按下的事件
            leftButton.OnPointerDownAsObservable().Subscribe(_ =>
            {
                leftButtonPressing = true;

                GameManager.Instance.currentShape.StepLeft();

                var timerObservable = Observable.Timer(TimeSpan.FromSeconds(0.3f))
                    .Where(_______ => leftButtonPressing);

                var stepLeftObservable = Observable.EveryUpdate()
                    .Where(___ => Time.frameCount % 3 == 0)
                    .Do(___ => { GameManager.Instance.currentShape.StepLeft(); });

                leftButtonLongPressTask = timerObservable.Concat(stepLeftObservable).Subscribe();
            });

            // 监听按钮抬起的事件
            leftButton.OnPointerUpAsObservable().Subscribe(_ =>
            {
                leftButtonPressing = false;
                
                if (leftButtonPressing != null)
                {
                    // 停止任务
                    leftButtonLongPressTask.Dispose();
                    leftButtonLongPressTask = null;
                }
            });
        }
        
        void RightButtonClickRegister()
        {
            bool rightButtonPressing = false;
            IDisposable rightButtonLongPressTask = null;
            
            rightButton.OnPointerDownAsObservable().Subscribe(_ =>
            {
                rightButtonPressing = true;

                GameManager.Instance.currentShape.StepRight();

                var timerObservable = Observable.Timer(TimeSpan.FromSeconds(0.3f))
                    .Where(_______ => rightButtonPressing);
                
                var stepRightObservable = Observable.EveryUpdate()
                    .Where(___ => Time.frameCount % 3 == 0)
                    .Do(__ => { GameManager.Instance.currentShape.StepRight(); });
                
                rightButtonLongPressTask = timerObservable.Concat(stepRightObservable).Subscribe();


                var delay = new DelayAction(0.3f);

                var repeat =
                    new RepeatNode(DelayAction.Allocate(0.1f,
                        () => { GameManager.Instance.currentShape.StepRight(); }),0);

                this.Sequence()
                    .Append(delay)
                    .Append(repeat)
                    .Begin()
                    .DisposeWhen(() => !rightButtonPressing);
            });

            rightButton.OnPointerUpAsObservable().Subscribe(_ =>
            {
                rightButtonPressing = false;
                if (rightButtonPressing != null)
                {
                    rightButtonLongPressTask.Dispose();
                    rightButtonLongPressTask = null;
                }
            });
        }
        
        public override void Init()
        {
            panelType = 0;
            mScoreSequence = DOTween.Sequence();
            mScoreSequence.SetAutoKill(false);

            LeftButtonClickRegister();
            RightButtonClickRegister();


            upButton.onClick.AddListener(() => GameManager.Instance.currentShape.RotateShape());


            downButton.OnPointerDownAsObservable().Subscribe(_ => { GameManager.Instance.currentShape.SpeedUp(); });

            downButton.OnPointerUpAsObservable().Subscribe(_ => { GameManager.Instance.currentShape.SpeedNormal(); });


            pauseButton.onClick.AddListener(() => EventManager.Instance.Fire(UIEvent.GAME_PAUSE));
            rocketButton.onClick.AddListener(() => GameManager.Instance.currentShape.Rocket());
        }

        public override void Hide()
        {
            if (gameObject.activeSelf)
            {
                gameObject.SetActive(false);
            }
        }

        public override void Destroy()
        {
        }


        private int mOldScore = 0;


        public override void UpdatePanelInfo(int[] info)
        {
            //update data
            //info[0]>>highest score
            //info[1]>>current score
            //info[2]>>row
            //info[3]>>level

            if (info == null || info.Length == 0)
            {
                return;
            }

            int newScore = info[1];
            mScoreSequence.Append(DOTween.To(delegate(float value)
            {
                var temp = Math.Floor(value);
                currentScoreText.text = temp + "";
            }, mOldScore, newScore, 0.4f));
            mOldScore = newScore;

            highestScoreText.text = info[0].ToString();
            currentScoreText.text = info[1].ToString();
            rowText.text = info[2].ToString();
            levelText.text = info[3].ToString();
        }
    }
}